package org.vectrics.client.webclient;

import org.apache.log4j.Logger;
import org.vectrics.SystemException;
import org.vectrics.VectricsException;
import org.vectrics.client.framework.ErrorFrame;

public class CommandDispatcher {
	private transient static Logger log = Logger.getLogger(CommandDispatcher.class);
	private HttpRequestThread commThread = null;
	static private CommandDispatcher instance = null;
	private ServiceConnection connection = null;
	private ConnectionStatusListener connectionStatusListener = null;
	private Requester requester = null;


	public CommandDispatcher() {
		super();
		requester = new HttpRequester();
		instance = this;
	}
	
	public CommandDispatcher(ServiceConnection connection, Requester requester) {
		super();
		this.connection = connection;
		this.requester = requester;
		instance = this;
	}
	
	static public CommandDispatcher getInstance() {
		return(instance);
	}
	
	
	
	private void startCommThread() throws VectricsException {
		if (connection == null) {
			throw new VectricsException("Starting communications thread before setting"
					+ " service connection information.");
		}
		commThread = new HttpRequestThread(connection);
		commThread.start();
	}
	
	
	public void execute(ServerCommand command) {
		try {
			if (connection == null) {
				throw new VectricsException("Executing command before setting service connection information.");
			}
			ResponseResult result = requester.execute(this.getConnection(), command);
			if (result == ResponseResult.NEED_AUTH) {
				log.debug("Server requires authentication, putting"
						+ " last stored user credentials into command and sending again");
				command.forceAuthentication();
				result = requester.execute(this.getConnection(), command);
			}
			if (this.getConnectionStatusListener() != null) {
				this.getConnectionStatusListener().statusUpdate(connection.getConnectionStatus());
			}
		}
		catch (VectricsException ve) {
			log.error("Exception executing command", ve);
			ErrorFrame.showError("Command Error", "Exception executing command", ve.getMessage());
				
			throw new SystemException("Exception executing command", ve);
		}
	}
	

	/**
	 * @return Returns the connection.
	 */
	public ServiceConnection getConnection() {
		return connection;
	}


	public void setConnection(ServiceConnection connection) {
		if (log.isDebugEnabled())
			log.debug("setConnection() called - connection user = " + connection.getUserName());
		
		this.connection = connection;
	}

	/**
	 * @return Returns the connectionStatusListener.
	 */
	public ConnectionStatusListener getConnectionStatusListener() {
		return connectionStatusListener;
	}

	/**
	 * @param connectionStatusListener The connectionStatusListener to set.
	 */
	public void setConnectionStatusListener(ConnectionStatusListener connectionStatusListener) {
		this.connectionStatusListener = connectionStatusListener;
	}

}
